const fs = require('fs');
const path = require('path');
const express = require('express');
const vite = require('vite');

let devServer;

const isTest = process.env.NODE_ENV === 'test' || !!process.env.VITE_TEST_BUILD;

process.env.MY_CUSTOM_SECRET = 'API_KEY_qwertyuiop';

async function createServer(root = process.cwd(), isProd = process.env.NODE_ENV === 'production') {
	const resolve = p => path.resolve(__dirname, p);

	const indexProd = isProd ? fs.readFileSync(resolve('dist/client/index.html'), 'utf-8') : '';

	const app = express();

	/**
	 * @type {import('vite').ViteDevServer}
	 */
	// let vite
	if (!isProd) {
		// vite = (await import('vite')).createServer({
		//   root,
		//   logLevel: isTest ? 'error' : 'info',
		//   server: {
		//     middlewareMode: 'ssr',
		//     watch: {
		//       // During tests we edit the files too fast and sometimes chokidar
		//       // misses change events, so enforce polling for consistency
		//       usePolling: true,
		//       interval: 100
		//     }
		//   }
		// })
		// // use vite's connect instance as middleware

		devServer = await vite.createServer({
			root,
			logLevel: isTest ? 'error' : 'info',
			server: {
				middlewareMode: 'ssr',
				watch: {
					// During tests we edit the files too fast and sometimes chokidar
					// misses change events, so enforce polling for consistency
					usePolling: true,
					interval: 100,
				},
			},
		});
		app.use(devServer.middlewares);
	} else {
		app.use(require('compression')());
		app.use(
			require('serve-static')(resolve('dist/client'), {
				index: false,
			})
		);
	}

	app.use('*', async (req, res) => {
		try {
			const url = req.originalUrl;

			let template, render;
			if (!isProd) {
				// always read fresh template in dev
				template = fs.readFileSync(resolve('index.html'), 'utf-8');
				template = await devServer.transformIndexHtml(url, template);
				render = (await devServer.ssrLoadModule('/src/entry-server.tsx')).render;
			} else {
				template = indexProd;
				render = (await import('./dist/server/entry-server.js')).render;
			}

			const context = { url };
			console.log(context);
			const appHtml = render(url, context);

			// if (context.url) {
			// 	// Somewhere a `<Redirect>` was rendered
			// 	return res.redirect(301, context.url);
			// }

			let html = template.replace(`<!--app-html-->`, appHtml);
			html = html.replace(`// app-context`, `window.context=${JSON.stringify(context)}`);

			res.status(200).set({ 'Content-Type': 'text/html' }).end(html);
		} catch (e) {
			!isProd && devServer.ssrFixStacktrace(e);
			console.log(e);
			res.status(500).end(e);
		}
	});

	return { app, vite };
}

if (!isTest) {
	createServer().then(({ app }) =>
		app.listen(3000, () => {
			console.log('http://localhost:3000');
		})
	);
}

// for test use
